//
//  RRegisterReactor.swift
//  RxStudy
//
//  Created by TRS-Mobile on 2022/10/8.
//  Copyright © 2022 season. All rights reserved.
//

import Foundation
import RxSwift
import RxCocoa
import ReactorKit

class RRegisterReactor: Reactor {
    enum Action {
        case inputName(String)
        case inputPwd(String)
        case inputRePwd(String)
        case register
    }
    
    enum Mutation {
        case setName(String)
        case setPwd(String)
        case setRePwd(String)
        case nameIsValid(Bool)
        case pwdIsValid(Bool)
        case rePwdIsValid(Bool)
        case everythingValid(Bool)
        case isRegister(Bool)
    }
    
    struct State {
        var name: String = ""
        var pwd: String = ""
        var rePwd: String = ""
        var usernameValid: Bool = false
        var passwordValid: Bool = false
        var rePasswordValid: Bool = false
        var everythingValid: Bool = false
        var isRegister: Bool = false
    }
    
    var initialState: State = State()
    
    let loginService: LoginServiceType
    
    init(initialState: State = State(), loginService: LoginServiceType) {
        self.initialState = initialState
        self.loginService = loginService
    }
    
    func mutate(action: Action) -> Observable<Mutation> {
        switch action {
        case .inputName(let name):
            return .concat([
                .just(.setName(name)),
                .just(.nameIsValid(name.count == 11)),
                .just(.everythingValid(name.count == 11 && currentState.passwordValid && currentState.rePasswordValid))
            ])
        case .inputPwd(let pwd):
            return .concat([
                .just(.setPwd(pwd)),
                .just(.pwdIsValid(pwd.count > 5)),
                .just(.everythingValid(pwd.count > 5 && currentState.usernameValid && currentState.rePasswordValid))
            ])
        case .inputRePwd(let pwd):
            return .concat([
                .just(.setRePwd(pwd)),
                .just(.rePwdIsValid(pwd == currentState.pwd)),
                .just(.everythingValid(pwd.count > 5 && currentState.passwordValid && currentState.usernameValid))
            ])
        case .register:
            guard currentState.everythingValid else {
                return .just(.isRegister(false))
            }
            
            return loginService
                .registerAndLogin(name: currentState.name, pwd: currentState.pwd, rePwd: currentState.rePwd)
                .map {Mutation.isRegister($0)}
        }
    }
    
    func reduce(state: State, mutation: Mutation) -> State {
        var state = state
        switch mutation {
        case .setName(let name):
            state.name = name
        case .setPwd(let pwd):
            state.pwd = pwd
        case .setRePwd(let pwd):
            state.rePwd = pwd
        case .nameIsValid(let valid):
            state.usernameValid = valid
        case .pwdIsValid(let valid):
            state.passwordValid = valid
        case .rePwdIsValid(let valid):
            state.rePasswordValid = valid
        case .everythingValid(let valid):
            state.everythingValid = valid
        case .isRegister(let valid):
            state.isRegister = valid
        }
        return state
    }
}

